package com.dap.log;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.slf4j.LoggerFactory;

import com.dap.exception.PlatformException;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.Loader;

/**
 * logback的日志配置管理实现
 */
public class LogbackDynamicConfigurator implements DynamicConfigurator {
	public final static String AUTOCONFIG_FILE = "logback.xml";
	final static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LogbackDynamicConfigurator.class);
	
	private LoggerContext loggerContext;
	public LogbackDynamicConfigurator() {
		loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
	}

	@Override
	public List<LoggerInfo> getLoggerList() {
		//创建新的LoggerContext准备加载配置,只加载配置	
		LoggerContext loggerContextForName = new LoggerContext();
		ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
		//配置文件
		URL url = Loader.getResource(AUTOCONFIG_FILE, myClassLoader);
		JoranConfigurator config = new JoranConfigurator();
		config.setContext(loggerContextForName);
		try {
			config.doConfigure(url);
		} catch (JoranException e) {
			LOGGER.error("动态加载logback配置文件异常", e);
			throw new PlatformException(e);
		}
		
		Iterator<Logger> it = loggerContextForName.getLoggerList().iterator();
		List<LoggerInfo> strList = new ArrayList<LoggerInfo>();
		//Iterator<Logger> it = loggerContext.getLoggerList().iterator();
		while (it.hasNext()) {
			Logger log = it.next();
			if(!log.isAdditive()||log.getName().equals(org.slf4j.Logger.ROOT_LOGGER_NAME)){
				strList.add(new LoggerInfo(log.getName(), loggerContext.getLogger(log.getName()).getLevel() != null ? loggerContext.getLogger(log.getName()).getLevel().toString() : loggerContext.getLogger(log.getName())
						.getEffectiveLevel().toString()));
			}
		}
		return strList;
	}

    @Override
    public void reloadDefaultConfiguration() {
        ContextInitializer ci = new ContextInitializer(loggerContext);
        URL url = ci.findURLOfDefaultConfigurationFile(true);

        loggerContext.reset();

        JoranConfigurator configurator = new JoranConfigurator();
        configurator.setContext(loggerContext);
        try {
            configurator.doConfigure(url);
        } catch (JoranException e) {
            throw new PlatformException(e);
        }
    }


    @Override
    public String getLoggerLevel(String loggerName) {
        if (loggerName == null) {
            return "";
        }

        loggerName = loggerName.trim();

        Logger logger = loggerContext.exists(loggerName);
        if (logger != null) {
            if (logger.getLevel() != null)
                return logger.getLevel().toString();
            return logger.getEffectiveLevel().toString();
        } else {
            return "";
        }
    }


    @Override
    public void setLoggerLevel(String loggerName, String levelStr) {
        if (loggerName == null) {
            return;
        }
        if (levelStr == null) {
            return;
        }
        loggerName = loggerName.trim();
        levelStr = levelStr.trim();

        // addInfo("Trying to set level " + levelStr + " to logger " + loggerName);

        Logger logger = loggerContext.getLogger(loggerName);
        if ("null".equalsIgnoreCase(levelStr)) {
            logger.setLevel(null);
        } else {
            Level level = Level.toLevel(levelStr, null);
            if (level != null) {
                logger.setLevel(level);
            }
        }
    }

}
